home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-04-17 | 4.5 KB | 201 lines | [TEXT/MACH] |
- \ INIT example which patches _GetResource
- \ with a call to _Sysbeep if type=CODE id=0
- \ Also patches _ExitToShell, using an absolutely
- \ AWFUL hack, but a _SetTrapAddress patch
- \ seems to be removed under Multifinder
- \ J. Langowski / MacTutor April 1989
-
- only forth also mac also assembler
-
- ( *** compiler support words for external definitions *** )
- : :xdef
- create -4 allot
- $4EFA w, ( JMP )
- 0 w, ( entry point to be filled later )
- 0 , ( length of routine to be filled later )
- here 6 - 76543
- ;
-
- : ;xdef { branch marker entry | -- }
- marker 76543 <> abort" xdef mismatch"
- entry branch - branch w!
- here branch - 2+ branch 2+ !
- ;
-
- : xlen 4 + @ ; ( get length word of external definition )
-
- \ **** ext procedure glue macros
-
- CODE ext.prelude
- LINK A6,#-700 ( 700 bytes of local Forth stack )
- MOVEM.L A0-A5/D0-D7,-(A7) ( save registers )
- MOVE.L A6,A3 ( setup local loop return stack )
- SUBA.L #500,A3 ( in the low 200 local stack bytes )
- RTS \ just to indicate the MACHro stops here
- END-CODE MACH
-
- CODE ext.epilogue
- MOVEM.L (A7)+,A0-A5/D0-D7 ( restore registers )
- UNLK A6
- RTS
- END-CODE MACH
-
- .trap _newPtr,SYS $A51E
-
- -4 CONSTANT thePort
- $904 CONSTANT CurrentA5
- $A9A0 CONSTANT tGetRes \ GetResource
- $A9F4 CONSTANT tExit \ ExitToShell
-
- \ |--------------------------------|
- \ | INIT resource code starts here |
- \ |--------------------------------|
-
- :xdef beeperINIT
-
- header PatchStart
- header oldGetRes
- DC.L 0
- header oldExit
- DC.L 0
-
- : GetResPatch
- ext.prelude
- CLR.L D0
- MOVE.W 8(A6),D0
- MOVE.L 10(A6),D1
- MOVE.L D0,-(A6)
- MOVE.L D1,-(A6)
-
- \ main FORTH code starts here
- \ this can be used to log any launch
- \ (i.e. GetResource CODE 0 ) to a log file
- \ which has to be created/opened by the INIT code
-
- ascii CODE = swap 0= and IF
- \ (call) debugger
- 1 (call) sysbeep
- THEN
- \ end of main code
-
- ext.epilogue
- LEA oldGetRes,A0
- MOVE.L (A0),A0
- JMP (A0)
- ;
-
- : ExitPatch
- ext.prelude
-
- \ main FORTH code starts here
- \ this can eventually be used to write a line to
- \ the same log file as before
- \ (call) debugger
- 1 (call) sysbeep
- \ end of main code
-
- ext.epilogue
- LEA oldExit,A0
- MOVE.L (A0),A0
- JMP (A0)
- ;
-
- header PatchEnd
-
- : movePatch { | length -- patch }
- ['] patchEnd ['] PatchStart - -> length
- length
- MOVE.L (A6)+,D0
- _newPtr,sys
- MOVE.L A0,-(A6)
- dup IF ( we have space in system heap )
- ['] PatchStart over length swap (call) blockMove drop
- THEN
- ;
-
- : myINIT { | patch pExit -- }
- movePatch -> patch
- patch IF
- \ patch _GetResource
- tGetRes (call) GetTrapAddress
- patch ! \ old GetResource
- ['] GetResPatch ['] PatchStart -
- patch + tGetRes (call) SetTrapAddress
- " GetResource patch has been installed." 0 0 0 (call) ParamText
- 1000 0 (call) NoteAlert drop
-
- \ patch _ExitToShell, using hack
- tExit (call) GetTrapAddress -> pExit
- pExit w@ $4EF9 =
- IF \ is it a JMP ? we're probably in Multifinder...
- pExit 2+ @
- patch 4+ ! \ old ExitToShell
- ['] ExitPatch ['] PatchStart -
- patch + pExit 2+ !
- \ patch directly into Juggler's innards. BOO!
- " ExitToShell patch in Multifinder." 0 0 0 (call) ParamText
- 1000 0 (call) NoteAlert drop
- ELSE
- pExit patch 4+ !
- ['] ExitPatch ['] PatchStart -
- patch + tExit (call) SetTrapAddress
- " ExitToShell patch in Finder." 0 0 0 (call) ParamText
- 1000 0 (call) NoteAlert drop
- THEN
- ELSE
- " Can't get memory for patches." 0 0 0 (call) ParamText
- 1000 0 (call) NoteAlert drop
- THEN
- ;
-
- : INITrun { | newA5 myGlobals [ 202 lallot ] theHandle -- }
- \ (call) debugger
- ['] beeperINIT (call) recoverHandle -> theHandle
- theHandle (call) Hlock drop
- ^ newA5
- MOVE.L (A6)+,A5 \ create area for QD globals
- MOVE.L A5,CurrentA5 \ A5 points to it
- ^ newA5 thePort + (call) InitGraf
- (call) InitFonts
- (call) InitWindows
- (call) TEInit
- 0 (call) InitDialogs
- (call) InitCursor
-
- myINIT \ call main INIT routine
-
- theHandle (call) HUnLock drop
- theHandle (call) DisposHandle drop
- ;
-
- : gINIT
- ext.prelude INITrun ext.epilogue
- MOVE.L A5,CurrentA5
- ;
-
- ' gINIT ;xdef
-
- ( *** creating the INIT file *** )
- : $create-res call CreateResFile call ResError L_ext ;
-
- : $open-res { addr | refNum -- result }
- addr call openresfile -> refNum
- call ResError L_ext
- dup not IF drop refNum THEN
- ;
-
- : $close-res call CloseResFile call ResError L_ext ;
-
- : make-init { | refNum -- }
- " theINIT" dup $create-res drop
- $open-res dup -> refNum call UseResFile
- ascii INIT 12 call GetResource
- ?dup IF call RmveResource THEN
- ['] beeperINIT dup xlen
- call PtrToHand drop ( result code )
- ascii INIT 12 call GetResource
- ?dup IF call RmveResource THEN
- ascii INIT 12 " Beeper" call AddResource
- refNum $close-res drop ( result code )
- ;
-